home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / nasanets.zip / COMPILE.C < prev    next >
C/C++ Source or Header  |  1990-06-07  |  18KB  |  434 lines

  1. /*=============================*/
  2. /*           NETS              */
  3. /*                             */
  4. /* a product of the AI Section */
  5. /* NASA, Johnson Space Center  */
  6. /*                             */
  7. /* principal author:           */
  8. /*       Paul Baffes           */
  9. /*                             */
  10. /* contributing authors:       */
  11. /*      Bryan Dulock           */
  12. /*      Chris Ortiz            */
  13. /*=============================*/
  14.  
  15.  
  16. /*
  17. ----------------------------------------------------------------------
  18.   Code For Production of Delivery Code (Prefix = CC_)
  19. ----------------------------------------------------------------------
  20.   This code is divided into 3 major sections:
  21.  
  22.   (1) include files
  23.   (2) externed functions
  24.   (3) subroutines
  25.  
  26.   Each section is further explained below.
  27. ----------------------------------------------------------------------
  28. */
  29.  
  30.  
  31. /*
  32. ----------------------------------------------------------------------
  33.   INCLUDE FILES
  34. ----------------------------------------------------------------------
  35. */
  36. #include  "common.h"
  37. #include  "weights.h"
  38. #include  "layer.h"
  39. #include  "net.h"
  40. #include  "netio.h"
  41.  
  42.  
  43. /*
  44. ----------------------------------------------------------------------
  45.   EXTERNED FUNCTIONS AND GLOBALS
  46. ----------------------------------------------------------------------
  47.   Below are the functions defined in other files which are used by the
  48.   code here. They are organized by section.
  49. ----------------------------------------------------------------------
  50. */
  51. extern int    N_reset_wts();
  52. extern int    N_save_wts();
  53. extern void   IO_my_get_string();
  54. extern void   IO_print();
  55. extern void   sys_delete_file();
  56. extern int    PA_check_signature();
  57.  
  58. extern char   IO_str[MAX_LINE_SIZE];
  59.  
  60.  
  61. /*
  62. ======================================================================
  63.   ROUTINES IN DELIVER.C                                                   
  64. ======================================================================
  65.   The routines in this file are grouped below by function. Each routine
  66.   is prefixed by the string "CC_" indicating that it is defined in the 
  67.   "deliver.c" file.  The types returned by the routines are also shown 
  68.   so that cross checking is more easily done between these functions
  69.   and the other files which intern them.
  70.  
  71.  
  72.   Type Returned                 Routine                                 
  73.   -------------                 -------                                 
  74.                                                                      
  75.   CREATION ROUTINES                                                    
  76.     void                        CC_create_delivery
  77.     void                        CC_setup_header
  78.     void                        CC_create_initialize
  79.     void                        CC_create_prop
  80.     void                        CC_create_cleanup
  81.     void                        CC_create_main
  82. ======================================================================
  83. */
  84.  
  85.  
  86. void  CC_create_delivery(ptr_net, net_file, wts_file)
  87. Net   *ptr_net;
  88. char  *net_file, *wts_file;
  89. /*
  90. ----------------------------------------------------------------------
  91.   Using the network as a guide, this routine creates a deliverable
  92.   file which is used simply to execute the network.
  93. ----------------------------------------------------------------------
  94. */
  95. BEGIN
  96.    FILE  *fp;
  97.    void  CC_setup_header(), CC_create_initialize(), CC_create_prop(),
  98.          CC_create_cleanup(), CC_create_main(), CC_set_name();
  99.    char  cc_file[MAX_WORD_SIZE], net_name[MAX_WORD_SIZE];
  100.  
  101.    /*-----------------------------------------------------*/
  102.    /* if the weights file is not in portable format, quit */
  103.    /*-----------------------------------------------------*/
  104.    if (PA_check_signature(wts_file, PORTABLE_FORMAT) == ERROR)
  105.       return;
  106.    
  107.    /*-------------------------------------*/
  108.    /* first, prompt for delivery file and */
  109.    /* check that the file can be opened   */
  110.    /*-------------------------------------*/
  111.    sprintf(IO_str, "\n   Enter name of delivery file: ");
  112.    IO_print(0);
  113.    IO_my_get_string(cc_file);
  114.    while (cc_file[0] == ENDSTRING) BEGIN
  115.       sprintf(IO_str, "\n   try again: ");
  116.       IO_print(0);
  117.       IO_my_get_string(cc_file);
  118.    ENDWHILE   
  119.    if( (fp = fopen(cc_file, "wt")) == NULL) BEGIN
  120.       sprintf(IO_str, "\n*** can't open %s file ***\n", cc_file);
  121.       IO_print(0);
  122.       return;
  123.    ENDIF
  124.  
  125.    /*------------------------------------*/
  126.    /* once the prompting is done, we can */
  127.    /* begin. First,though, save off the  */
  128.    /* current network weights since they */
  129.    /* will be trashed in the process of  */
  130.    /* making the delivery file.          */
  131.    /*------------------------------------*/
  132.    N_save_wts(ptr_net, "temp.wts", FAST_FORMAT);
  133.  
  134.    /*---------------------------------------------*/
  135.    /* Next, check the weights to see that they    */
  136.    /* are compatible with the net's configuration */
  137.    /* and if not, print out message and abort.    */
  138.    /*---------------------------------------------*/
  139.    if (N_reset_wts(ptr_net, wts_file, PORTABLE_FORMAT) == ERROR) BEGIN
  140.       sprintf(IO_str, "\n*** weights not compatible with network");
  141.       IO_print(0);
  142.    ENDIF
  143.    
  144.    else BEGIN   
  145.       /*-------------------------------------------*/
  146.       /* setup the net_name variable using the net */
  147.       /* ID so that this code will be unique.      */
  148.       /*-------------------------------------------*/
  149.       CC_set_name(net_name, net_file);
  150.    
  151.       /*------------------------------------------------*/
  152.       /* Create the headers and routines which are used */
  153.       /* to initialize, propagate, and free a network.  */
  154.       /*------------------------------------------------*/
  155.       CC_setup_header(fp, ptr_net, net_name);
  156.       CC_create_main(fp, net_name);
  157.       CC_create_initialize(fp, ptr_net, net_file, wts_file, net_name);
  158.       CC_create_prop(fp, net_name);
  159.       CC_create_cleanup(fp, net_name);
  160.    ENDELSE
  161.    
  162.    /*-------------------------------------------*/
  163.    /* reset the weights of the network to their */
  164.    /* former values, throw away the temporary   */
  165.    /* file, and close the delivery file.        */
  166.    /*-------------------------------------------*/
  167.    N_reset_wts(ptr_net, "temp.wts", FAST_FORMAT);
  168.    sys_delete_file("temp.wts");
  169.    fclose(fp);
  170.  
  171. END /* CC_create_delivery */
  172.  
  173.  
  174. void  CC_set_name(net_name, net_file)
  175. char  *net_name, *net_file;
  176. /*
  177. ----------------------------------------------------------------------
  178.    Using the name of the network specification file (stored in the
  179.    "net_file" parameter) this routine sets up the string which will be
  180.    used as a precursor to all variable and routine names in the delivery
  181.    file. The idea is to read until a "." or the end of the string is
  182.    encountered.
  183. ----------------------------------------------------------------------
  184. */
  185. BEGIN
  186.    int  i = 0;
  187.    
  188.    while ((net_file[i] != '.') && (net_file[i] != ENDSTRING)) BEGIN
  189.       net_name[i] = net_file[i];      
  190.       /*-------------------------------------------------*/
  191.       /* I know this is stupid, but the stupid masscomp  */
  192.       /* C compiler choked on an autoincrement of "i"    */
  193.       /* within the array reference. So I had to come    */
  194.       /* down a peg to the brute force approach.         */
  195.       /*-------------------------------------------------*/
  196.       i++;
  197.    ENDWHILE
  198.    net_name[i++] = '_';
  199.    net_name[i] = ENDSTRING;
  200.  
  201. END /* CC_set_name */
  202.  
  203.  
  204. void  CC_setup_header(fp, ptr_net, name)
  205. FILE  *fp;
  206. Net   *ptr_net;
  207. char  *name;
  208. /*
  209. ----------------------------------------------------------------------
  210.   This routine prints out the initial includes and defines for the 
  211.   delivery file. Also, two arrays of floating point numbers are 
  212.   declared as global variables; these will be the arrays which are
  213.   used to put inputs into the network.
  214. ----------------------------------------------------------------------
  215. */
  216. BEGIN   
  217.    fprintf(fp, "\n/*=============================*/");
  218.    fprintf(fp, "\n/* NETS Network Delivery File  */");
  219.    fprintf(fp, "\n/*                             */");
  220.    fprintf(fp, "\n/* a product of the AI Section */");
  221.    fprintf(fp, "\n/* NASA, Johnson Space Center  */");
  222.    fprintf(fp, "\n/*                             */");
  223.    fprintf(fp, "\n/* principal author:           */");
  224.    fprintf(fp, "\n/*       Paul Baffes           */");
  225.    fprintf(fp, "\n/*                             */");
  226.    fprintf(fp, "\n/* contributing authors:       */");
  227.    fprintf(fp, "\n/*      Brian Dulock           */");
  228.    fprintf(fp, "\n/*      Chris Ortiz            */");
  229.    fprintf(fp, "\n/*=============================*/");
  230.    
  231.    fprintf(fp, "\n\n#include \"common.h\"");
  232.    fprintf(fp, "\n#include \"weights.h\"");
  233.    fprintf(fp, "\n#include \"layer.h\"");
  234.    fprintf(fp, "\n#include \"net.h\"");
  235.    fprintf(fp, "\n#include \"netio.h\"");
  236.    fprintf(fp, "\n#define  INPUT_SIZE   %d", 
  237.                ptr_net->input_layer->num_nodes);
  238.    fprintf(fp, "\n#define  OUTPUT_SIZE  %d",
  239.                ptr_net->output_layer->num_nodes);
  240.    
  241.    fprintf(fp, "\n\nextern Net   *B_create_net();");
  242.    fprintf(fp, "\nextern Net   *B_free_net();");
  243.    fprintf(fp, "\nextern int    N_reset_wts();");
  244.    fprintf(fp, "\nextern void   P_prop_input();");
  245.    fprintf(fp, "\nextern void   PA_initialize();");
  246.    fprintf(fp, "\nextern void   D_initialize();");
  247.    fprintf(fp, "\nextern Sint   C_float_to_Sint();");
  248.    fprintf(fp, "\nextern float  C_Sint_to_float();");
  249.    fprintf(fp, "\nextern void   sys_init_rand();");
  250.    
  251.    fprintf(fp, "\n\n\n/*------------------*/");
  252.    fprintf(fp, "\n/* Global Variables */");
  253.    fprintf(fp, "\n/*------------------*/");
  254.    fprintf(fp, "\nfloat  %sInputs[INPUT_SIZE];", name);
  255.    fprintf(fp, "\nfloat  %sOutputs[OUTPUT_SIZE];", name);
  256.    fprintf(fp, "\nNet   *%sNetPtr;", name);
  257.      
  258. END /* CC_setup_header */
  259.  
  260.  
  261. void  CC_create_main(fp, name)
  262. FILE  *fp;
  263. char  *name;
  264. /*
  265. ----------------------------------------------------------------------
  266.    This code creates an example main program for the user. All that is
  267.    done here is to fill up the Inputs array once, propagate it through
  268.    the network, and print out the results.
  269. ----------------------------------------------------------------------
  270. */
  271. BEGIN
  272.  
  273.    fprintf(fp, "\n\n\n/*-------------------------------------------------------------*/");
  274.    fprintf(fp, "\n/* Here is an example of a main routine. Note that the network */");
  275.    fprintf(fp, "\n/* is initialized once BEFORE before the propagate routine is  */");
  276.    fprintf(fp, "\n/* called and cleaned up once AFTER ALL calls to propagate are */");
  277.    fprintf(fp, "\n/* completed. That is, you only need to call initialize once   */");
  278.    fprintf(fp, "\n/* to build the network and once to throw it away.  Note also  */");
  279.    fprintf(fp, "\n/* that the inputs and outputs are communicated via the two    */");
  280.    fprintf(fp, "\n/* global arrays defined at the top of the file.               */");
  281.    fprintf(fp, "\n/*                                                             */");
  282.    fprintf(fp, "\n/* This routine should be replaced with your own routines(s)   */");
  283.    fprintf(fp, "\n/* designed for your application.                              */");
  284.    fprintf(fp, "\n/*-------------------------------------------------------------*/");
  285.    fprintf(fp, "\nmain()");
  286.    fprintf(fp, "\n{");
  287.    fprintf(fp, "\n   int   i;");
  288.    fprintf(fp, "\n   void  %sinitialize();", name);
  289.    fprintf(fp, "\n   void  %spropagate();", name);
  290.    fprintf(fp, "\n   void  %scleanup();", name);
  291.    fprintf(fp, "\n\n   %sinitialize();", name);
  292.    fprintf(fp, "\n\n   for (i = 0; i < INPUT_SIZE; i++)");
  293.    fprintf(fp, "\n      %sInputs[i] = .9;", name);
  294.    fprintf(fp, "\n   %spropagate();", name);
  295.    fprintf(fp, "\n   for (i = 0; i < OUTPUT_SIZE; i++)");
  296. #if  USE_SCALED_INTS
  297.    fprintf(fp, "\n      printf(\"\\n output %%d = %%7.3f\", i, %sOutputs[i]);", name);
  298. #else
  299.    fprintf(fp, "\n      printf(\"\\n output %%d = %%10.6f\", i, %sOutputs[i]);", name);
  300. #endif
  301.    fprintf(fp, "\n\n   %scleanup();", name);
  302.    fprintf(fp, "\n\n} /* example main program */");
  303.  
  304. END /* CC_create_main */
  305.  
  306.  
  307. void  CC_create_initialize(fp, ptr_net, net_file, wts_file, name)
  308. FILE  *fp;
  309. Net   *ptr_net;
  310. char  *net_file, *wts_file, *name;
  311. /*
  312. ----------------------------------------------------------------------
  313.   This routine creates an initialization file for the network. Mostly 
  314.   this involves setting up the net and its weights, although it also
  315.   involves some of the same initialization calls made in the "initialize"
  316.   routine of netmain.c. Note I duplicate those calls here so that the
  317.   user does not have to include that file in his compile (which we 
  318.   DONT want included since it has a "main" function).
  319. ----------------------------------------------------------------------
  320. */
  321. BEGIN   
  322.    fprintf(fp, "\n\n\n/*---------------------------------------------*/");
  323.    fprintf(fp, "\n/* call this routine once to setup the network */");
  324.    fprintf(fp, "\n/*---------------------------------------------*/");
  325.    fprintf(fp, "\nvoid  %sinitialize()", name);
  326.    fprintf(fp, "\n{");
  327.    fprintf(fp, "\n   int  i;");
  328.    
  329.    /*-----------------------------------------------*/
  330.    /* write code for calling initializationroutines */
  331.    /*-----------------------------------------------*/
  332.    fprintf(fp, "\n\n   /*--------------------------*/");
  333.    fprintf(fp, "\n   /* call initialization code */");
  334.    fprintf(fp, "\n   /*--------------------------*/");
  335.    fprintf(fp, "\n   %sNetPtr = NULL;", name);
  336.    fprintf(fp, "\n   sys_init_rand();");
  337.    fprintf(fp, "\n   PA_initialize();");
  338.    fprintf(fp, "\n   D_initialize();");
  339.    
  340.    /*--------------------------------------------*/
  341.    /* code for creating network and setting bias */
  342.    /*--------------------------------------------*/
  343.    fprintf(fp, "\n\n   /*----------------*/");
  344.    fprintf(fp, "\n   /* create network */");
  345.    fprintf(fp, "\n   /*----------------*/");
  346.    fprintf(fp, "\n   %sNetPtr = B_create_net(1, \"%s\");", name, net_file);
  347.    fprintf(fp, "\n   %sNetPtr->use_biases = %s;", name,
  348.                ((ptr_net->use_biases == TRUE) ? "TRUE" : "FALSE"));
  349.    fprintf(fp, "\n   %sNetPtr->num_inputs  = INPUT_SIZE;", name);
  350.    fprintf(fp, "\n   %sNetPtr->num_outputs = OUTPUT_SIZE;", name);
  351.       
  352.    fprintf(fp, "\n\n   /*--------------------------------------------*/");
  353.    fprintf(fp, "\n   /* reset weights and the input, output arrays */");
  354.    fprintf(fp, "\n   /*--------------------------------------------*/");
  355.    fprintf(fp, "\n   N_reset_wts(%sNetPtr, \"%s\", PORTABLE_FORMAT);", name, wts_file);
  356.    fprintf(fp, "\n   for (i = 0; i < INPUT_SIZE; i++)");
  357.    fprintf(fp, "\n      %sInputs[i] = 0.0;", name);
  358.    fprintf(fp, "\n   for (i = 0; i < OUTPUT_SIZE; i++)");
  359.    fprintf(fp, "\n      %sOutputs[i] = 0.0;", name);
  360.    fprintf(fp, "\n\n} /* %sinitialize */", name);
  361.    
  362. END /* CC_create_initialize */
  363.  
  364.  
  365. void  CC_create_prop(fp, name)
  366. FILE  *fp;
  367. char  *name;
  368. /*
  369. ----------------------------------------------------------------------
  370.   This guy creates the propagate routine for pushing info through a 
  371.   net. It assumes that the calling routine has loaded the Inputs array
  372.   from which it will read its inputs. After propagating it puts the 
  373.   outputs on the Outputs arrray. Again, the caller may do with these
  374.   arrays as it likes, since they are global. However, if these conventions
  375.   are not followed then there is no guaranty on the behavior of the 
  376.   network.
  377. ----------------------------------------------------------------------
  378. */
  379. BEGIN
  380.    fprintf(fp, "\n\n\n/*------------------------------------------------*/");
  381.    fprintf(fp, "\n/* call this routine every time you want to query */");
  382.    fprintf(fp, "\n/* the network. Note that it assumes the \"Input\"  */");
  383.    fprintf(fp, "\n/* array is already loaded with input values      */");
  384.    fprintf(fp, "\n/*------------------------------------------------*/");
  385.    fprintf(fp, "\nvoid  %spropagate()", name);
  386.    fprintf(fp, "\n{");
  387.    fprintf(fp, "\n   int  i;");
  388.    fprintf(fp, "\n   Layer  *input, *output;");
  389.    
  390.    fprintf(fp, "\n\n   /*------------------------------------------*/");
  391.    fprintf(fp, "\n   /* get pointers to network input and output */");
  392.    fprintf(fp, "\n   /*------------------------------------------*/");
  393.    fprintf(fp, "\n   input  = %sNetPtr->input_layer;", name);
  394.    fprintf(fp, "\n   output = %sNetPtr->output_layer;", name);
  395.    fprintf(fp, "\n\n   /*--------------------------------------*/");
  396.    fprintf(fp, "\n   /* load input values; propagate network */");
  397.    fprintf(fp, "\n   /*--------------------------------------*/");
  398.    fprintf(fp, "\n   for (i = 0; i < INPUT_SIZE; i++)");
  399.    fprintf(fp, "\n      input->node_outputs[i] = C_float_to_Sint");
  400.    fprintf(fp, "(%sInputs[i]);", name);
  401.    fprintf(fp, "\n   P_prop_input(%sNetPtr);", name);
  402.    
  403.    fprintf(fp, "\n\n   /*---------------------*/");
  404.    fprintf(fp, "\n   /* setup output values */");
  405.    fprintf(fp, "\n   /*---------------------*/");
  406.    fprintf(fp, "\n   for (i = 0; i < OUTPUT_SIZE; i++)");
  407.    fprintf(fp, "\n      %sOutputs[i] = C_Sint_to_float", name);
  408.    fprintf(fp, "(output->node_outputs[i]);");
  409.    fprintf(fp, "\n\n} /* %spropagate */", name);
  410.  
  411. END /* CC_create_prop */
  412.  
  413.  
  414. void  CC_create_cleanup(fp, name)
  415. FILE  *fp;
  416. char  *name;
  417. /*
  418. ----------------------------------------------------------------------
  419.   This routine is provided as a means for removing the memory assigned
  420.   to the network during its execution. 
  421. ----------------------------------------------------------------------
  422. */
  423. BEGIN
  424.    fprintf(fp, "\n\n\n/*------------------------------------------*/");
  425.    fprintf(fp, "\n/* call this routine once to free the space */");
  426.    fprintf(fp, "\n/* used by the network.                     */");
  427.    fprintf(fp, "\n/*------------------------------------------*/");
  428.    fprintf(fp, "\nvoid  %scleanup()", name);
  429.    fprintf(fp, "\n{");
  430.    fprintf(fp, "\n   B_free_net(%sNetPtr);", name);
  431.    fprintf(fp, "\n\n} /* %scleanup */", name);
  432.  
  433. END /* CC_create_prop */
  434.